package com.android.xcalendar.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.android.xcalendar.model.Event;
import com.android.xcalendar.model.Location;

public class XCalendarContentManager {
	public static final String LOG_TAG = "XCalendarContentManager";
	public static XCalendarContentManager uniqueInstance;

	public static XCalendarContentManager getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new XCalendarContentManager();
			return uniqueInstance;
		}
		return uniqueInstance;
	}

	XCalendarAPIManager apiManager = XCalendarAPIManager.getInstance();

	private String jsonText;
	private JSONObject jsonObject;
	private String userName;
	private String password;
	private List<Event> events = new ArrayList<Event>();
	private ArrayList<Date> dates = new ArrayList<Date>();
	private List<Event> eventsOfDay = new ArrayList<Event>();
	private Event selectedEvent;
	private String dayViewDateString;
	private int jsonMessageFlag; // 0 means no error, 1 stands for an error

	// occurred
	private List<Location> locations = new ArrayList<Location>();

	public int getJsonMessageFlag() {
		return jsonMessageFlag;
	}

	public void setJsonMessageFlag(int jsonMessageFlag) {
		this.jsonMessageFlag = jsonMessageFlag;
	}

	public String getJsonText() {
		return jsonText;
	}

	public void setJsonText(String jsonText) {
		this.jsonText = jsonText;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public List<Event> getEvents() {
		return events;
	}

	public void setEvents(List<Event> events) {
		this.events = events;
	}

	public List<Location> getLocations() {
		return locations;
	}

	public void setLocations(List<Location> locations) {
		this.locations = locations;
	}

	public ArrayList<Date> getDates() {
		return dates;
	}

	public void setDates(ArrayList<Date> dates) {
		this.dates = dates;
	}

	public List<Event> getEventsOfDay() {
		return eventsOfDay;
	}

	public void setEventsOfDay(List<Event> eventsOfDay) {
		this.eventsOfDay = eventsOfDay;
	}

	public Event getSelectedEvent() {
		return selectedEvent;
	}

	public void setSelectedEvent(Event selectedEvent) {
		this.selectedEvent = selectedEvent;
	}

	public String getDayViewDateString() {
		return dayViewDateString;
	}

	public void setDayViewDateString(String dayViewDateString) {
		this.dayViewDateString = dayViewDateString;
	}

	public void connect(String url) {
		jsonText = apiManager.connect(url);
		Log.d("json", jsonText);
		if (jsonText.contains("error")) {
			this.jsonMessageFlag = 1;
		} else {
			this.jsonMessageFlag = 0;
			parseJsonText();
		}

	}

	private void parseJsonText() {
		try {
			events.clear();
			locations.clear();
			eventsOfDay.clear();
			dates.clear();
			jsonObject = new JSONObject(jsonText);
			userName = jsonObject.getString("userName");
			password = jsonObject.getString("password");
			if (!jsonObject.has("events"))
				;
			else if (jsonObject.optJSONArray("events") == null) {
				JSONObject tmpJSONObjet = jsonObject.optJSONObject("events");
				parseEvents(tmpJSONObjet);
			} else {
				JSONArray eventsArray = jsonObject.optJSONArray("events");
				int i = 0;
				while (eventsArray.optJSONObject(i) != null) {
					JSONObject tmpJSONObjet = eventsArray.optJSONObject(i);
					parseEvents(tmpJSONObjet);
					i++;
				}
			}

			// parse locations
			if (!jsonObject.has("locations"))
				;
			else if (jsonObject.optJSONArray("locations") == null) {
				JSONObject tmpJsonObject = jsonObject.optJSONObject("locations");
				parseLocations(tmpJsonObject);
			} else {
				JSONArray locationsArray = jsonObject.optJSONArray("locations");
				int j = 0;
				while (locationsArray.optJSONObject(j) != null) {
					JSONObject tmpJsonObject = locationsArray.optJSONObject(j);
					parseLocations(tmpJsonObject);
					j++;
				}
			}

		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	public void parseEvents(JSONObject tmpJSONObjet) {
		//		boolean alldayFlag = (tmpJSONObjet.optString("allday") == "true") ? true
				//				: false;
				DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
						String sTimeBfParse = tmpJSONObjet.optString("startTime");
						String eTimeBfParse = tmpJSONObjet.optString("endTime");
						String rTimeBfParse = tmpJSONObjet.optString("remindTime");
						Date startTime = new Date();
						Date endTime = new Date();
						Date remindTime = new Date();
						try {
							startTime = df.parse(sTimeBfParse);
							endTime = df.parse(eTimeBfParse);
							remindTime = df.parse(rTimeBfParse);
						} catch (ParseException e) {
							e.printStackTrace();
						}
						Event newEvent = new Event();
						newEvent.setKey(tmpJSONObjet.optString("key"));
						newEvent.setUserKey(tmpJSONObjet.optString("userKey"));
						newEvent.setTitle(tmpJSONObjet.optString("title"));
						newEvent.setStartTime(startTime);
						newEvent.setEndTime(endTime);
						newEvent.setRemindTime(remindTime);
						newEvent.setImportant((tmpJSONObjet.optString("important") == "true") ? true: false);
						newEvent.setDescription(tmpJSONObjet.optString("description"));
						newEvent.setLocationKey(tmpJSONObjet.optString("locationKey"));
						events.add(newEvent);
						dates.add(startTime);
						Log.d("event", newEvent.getTitle()+newEvent.getStartTime().toString());
	}

	public void parseLocations(JSONObject tmpJSONObjet) {
		Double latitude = (double) 0;
		Double longitude = (double) 0;
		try{
			latitude = Double.parseDouble(tmpJSONObjet.optString("latitude"));
			longitude = Double.parseDouble(tmpJSONObjet.optString("longitude"));
		}catch(NumberFormatException e){
			e.printStackTrace();
		}
		Location newLocation = new Location();
		newLocation.setKey(tmpJSONObjet.optString("key"));
		newLocation.setLocationName(tmpJSONObjet.optString("locationName"));
		newLocation.setLatitude(latitude);
		newLocation.setLongitude(longitude);
		newLocation.setUserKey(tmpJSONObjet.optString("userKey"));
		locations.add(newLocation);
		Log.d("location", newLocation.getLocationName()+newLocation.getLatitude().toString());
	}

	private String monthConverter(int month) {
		switch (month) {
		case 0:
			return "January";
		case 1:
			return "February";
		case 2:
			return "March";
		case 3:
			return "April";
		case 4:
			return "May";
		case 5:
			return "June";
		case 6:
			return "July";
		case 7:
			return "August";
		case 8:
			return "September";
		case 9:
			return "October";
		case 10:
			return "November";
		case 11:
			return "December";
		default:
			return "";
		}
	}

	public void initDayView(int year, int month, int day) {
		eventsOfDay.clear();
		dayViewDateString = monthConverter(month) + " " + Integer.toString(day)
		+ ", " + Integer.toString(year);
		for (Event event : events) {
			if ((event.getStartTime().getYear() + 1900) == year
					&& event.getStartTime().getMonth() == month
					&& event.getStartTime().getDate() == day)
				eventsOfDay.add(event);
		}
	}

	public void registerC2DMId(String id) {
		String urlString=Constants.C2DM+"userName="+userName+"&registrationID="+id+"/";
		Log.d(LOG_TAG, urlString);
		apiManager.connect(urlString);
	}
}